# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : running_info_view.py
# Time       ：2023/11/3 14:00
# Author     ：YangYong
# version    ：python 3.10
# Description：运行信息
"""
from flask_restx import Resource, fields
from sqlalchemy import desc

from apis.data_screen import data_screen_ns
from apis.data_screen.schema.running_info_schema import ProcessInfoSchema, TaskNodeInfoSchema, RunningTaskSchema
from apis.orderlines.models import ProcessInstance, TaskInstance
from orderlines.utils.orderlines_enum import ProcessStates, TaskStates
from public.api_utils.api_decorator import handle_api_error
from public.base_model import db
from public.base_response import generate_response, MarshalModel

process_info_model = data_screen_ns.model(
    'process_info_ds',
    {
        'name': fields.String(),
        'status': fields.String(),
        'progress': fields.Integer(),
        'process_instance_id': fields.String(),
    }
)
running_task_model = data_screen_ns.model(
    'running_task_ds',
    {
        'task_name': fields.String(),
        'task_status': fields.String(),
        'task_result': fields.Raw(),
        'task_error': fields.Raw(),
        'start_time': fields.String(),
        'end_time': fields.String(),
    }
)
task_nodes_model = data_screen_ns.model(
    'task_nodes_ds',
    {
        'task_name': fields.String(),
        'task_status': fields.String(),
        'color': fields.String(),
        'icon': fields.String(),
    }
)

running_info = {
    'process_info': fields.Nested(process_info_model),
    'task_nodes': fields.Nested(task_nodes_model, as_list=True),
    'running_task': fields.Nested(running_task_model),
}

running_info_marshal = MarshalModel('ds_running_info', data_screen_ns)


class RunningInfoView(Resource):
    url = '/running_info'

    def __init__(self, *args, **kwargs):
        super(RunningInfoView, self).__init__(*args, **kwargs)
        self.process_instance_id = None

    def get_process_info(self):
        """获取流程信息"""
        obj = db.session.query(
            ProcessInstance.process_name.label('name'),
            ProcessInstance.process_status.label('status'),
            ProcessInstance.process_instance_id.label('process_instance_id')
        ).filter(
            ProcessInstance.process_status == ProcessStates.blue.value,
            ProcessInstance.active == 1
        ).order_by(desc(ProcessInstance.id)).first()

        if not obj:
            obj = db.session.query(
                ProcessInstance.process_name.label('name'),
                ProcessInstance.process_status.label('status'),
                ProcessInstance.process_instance_id.label('process_instance_id')
            ).filter(
                ProcessInstance.process_status == ProcessStates.green.value,
                ProcessInstance.active == 1
            ).order_by(desc(ProcessInstance.id)).first()
        process_info = ProcessInfoSchema().dump(obj) if obj else {}
        self.process_instance_id = process_info.get('process_instance_id')
        return process_info

    def get_task_nodes(self):
        """获取任务节点"""
        objs = db.session.query(TaskInstance).filter(
            TaskInstance.process_instance_id == self.process_instance_id,
            TaskInstance.active == 1
        ).all()
        return TaskNodeInfoSchema().dump(objs, many=True)

    def get_running_task(self):
        """获取正在运行的任务"""
        obj = db.session.query(
            TaskInstance.task_name.label('task_name'),
            TaskInstance.task_status.label('task_status'),
            TaskInstance.task_result.label('task_result'),
            TaskInstance.task_error_info.label('task_error'),
            TaskInstance.start_time.label('start_time'),
            TaskInstance.end_time.label('end_time')
        ).filter(
            TaskInstance.process_instance_id == self.process_instance_id,
            TaskInstance.task_status == TaskStates.blue.value,
            TaskInstance.active == 1
        ).order_by(desc(TaskInstance.id)).first()
        if not obj:
            obj = db.session.query(
                TaskInstance.task_name.label('task_name'),
                TaskInstance.task_status.label('task_status'),
                TaskInstance.task_result.label('task_result'),
                TaskInstance.task_error_info.label('task_error'),
                TaskInstance.start_time.label('start_time'),
                TaskInstance.end_time.label('end_time'),
            ).filter(
                TaskInstance.process_instance_id == self.process_instance_id,
                TaskInstance.active == 1
            ).order_by(desc(TaskInstance.id)).first()

        return RunningTaskSchema().dump(obj) if obj else {}

    @handle_api_error()
    @data_screen_ns.doc(description='运行信息')
    @data_screen_ns.marshal_with(running_info_marshal.detail_response(running_info, False))
    def get(self):
        """运行信息"""
        process_info = self.get_process_info()
        task_nodes = self.get_task_nodes()
        running_task = self.get_running_task()
        response_data = {
            'process_info': process_info,
            'task_nodes': task_nodes,
            'running_task': running_task
        }
        return generate_response(response_data)
